﻿/********************************************************************************
 * Developed by Phil Tyler (http://www.laidbackcoder.co.uk)
 * 
 * Cryptosolic is Licensed under the GNU Lesser General Public License (LGPL)
 * http://cryptosolic.codeplex.com/license
 * *****************************************************************************/
using System.Security.Cryptography;
using Cryptosolic.Security.Hashing;

namespace Cryptosolic.Security.Encryption.Symmetric
{
	/// <summary>
	/// Symmetric Encryption Algorithm Interface
	/// </summary>
    public interface ISymmetricEncryptionAlgorithm
    {
        /// <summary>
        /// Encrypt the Human Readable Data
        /// </summary>
        /// <param name="data">Human Readable Data to be Encrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Encrypted Data</returns>
        CipherText EncryptData(byte[] data, string symmetricKey, byte[] iV);

        /// <summary>
        /// Encrypt the Human Readable Data
        /// </summary>
        /// <param name="data">Human Readable Data to be Encrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="salt">Salt</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Encrypted Data</returns>
        CipherText EncryptData(byte[] data, string symmetricKey, string salt, byte[] iV);
        
        /// <summary>
        /// Encrypt the Human Readable Data
        /// </summary>
        /// <param name="data">Human Readable Data to be Encrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Encrypted Data</returns>
        CipherText EncryptData(string data, string symmetricKey, byte[] iV);

        /// <summary>
        /// Encrypt the Human Readable Data
        /// </summary>
        /// <param name="data">Human Readable Data to be Encrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="salt">Salt</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Encrypted Data</returns>
        CipherText EncryptData(string data, string symmetricKey, string salt, byte[] iV);

        /// <summary>
        /// Decrypt Encrypted Data
        /// </summary>
        /// <param name="data">Encrypted Data to be Decrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Human Readable Data</returns>
        PlainText DecryptData(byte[] data, string symmetricKey, byte[] iV);

        /// <summary>
        /// Decrypt Encrypted Data
        /// </summary>
        /// <param name="data">Encrypted Data to be Decrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="salt">Salt</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Human Readable Data</returns>
        PlainText DecryptData(byte[] data, string symmetricKey, string salt, byte[] iV);

        /// <summary>
        /// Decrypt Encrypted Data
        /// </summary>
        /// <param name="data">Encrypted Data to be Decrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Human Readable Data</returns>
        PlainText DecryptData(string data, string symmetricKey, byte[] iV);

        /// <summary>
        /// Decrypt Encrypted Data
        /// </summary>
        /// <param name="data">Encrypted Data to be Decrypted</param>
        /// <param name="symmetricKey">Symetric Encryption/Decryption Key</param>
        /// <param name="salt">Salt</param>
        /// <param name="iV">Initialisation Vector</param>
        /// <returns>Human Readable Data</returns>
        PlainText DecryptData(string data, string symmetricKey, string salt, byte[] iV);

        /// <summary>
		/// Generate a Random Initialisation Vector
		/// </summary>
		/// <returns>Random Bytes of relative size to the Cipher's Block Size</returns>
        byte[] GenerateRandomIV();
        
        /// <summary>
		/// Generate a Random Symmetric Key
		/// </summary>
		/// <returns>Random Key of relative size to the Cipher's Key Size</returns>
        string GenerateRandomKey(); 
        
        /// <summary>
		/// Generate a Random Symmetric Salt
		/// </summary>
		/// <returns>Random Salt of relative size to the Cipher's Key Size</returns>
        string GenerateRandomSalt(); 
        
        /// <summary>
        /// Key Size of Cipher (in bits)
        /// </summary>
        int KeySize { get; }
        
        /// <summary>
        /// Block Size of Cipher (in bits)
        /// </summary>
        int BlockSize { get; }
        
        /// <summary>
        /// Number of Iterations to be used in the Hashing Algorithm
        /// </summary>
        int HashIterations { get; set; }	
        
        /// <summary>
        /// Method to Pad Cipher Text
        /// </summary>
		BytePaddingMode Padding { get; }
		
		/// <summary>
        /// Method used to Undertake Encryption/Decryption
        /// </summary>
		BlockCipherMode Mode  { get; }
		
		/// <summary>
        /// Hashing Algorithm used to Generate Key
        /// </summary>
       	IHashingAlgorithm HashingAlg { get; }
    }
}
